package org.demo.base.jdbc.util;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.ListIterator;

public class MyDataSource {

    private LinkedList<ConnectionExtends> connectionLinkedList;

    private int minSizes = 5;

    private int maxSizes = 10;

    private String driverClass;

    private String url;

    private String username;

    private String password;


    public void init(){
        connectionLinkedList = new LinkedList<ConnectionExtends>();
        for (int i=1;i<=maxSizes;i++){
            try {
                Class.forName(driverClass);
                Connection connection = DriverManager.getConnection(url, username, password);
                ConnectionExtends connectionExtends = new ConnectionExtends();

                connectionExtends.setConnection(connection);
                connectionExtends.setFreeStatus(true);
                connectionLinkedList.add(connectionExtends);
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }

    }

    public Connection getConnection() throws SQLException {
        ListIterator<ConnectionExtends> connectionExtendsListIterator = connectionLinkedList.listIterator();
        while (connectionExtendsListIterator.hasNext()){
            final ConnectionExtends connectionExtends = connectionExtendsListIterator.next();
            Boolean freeStatus = connectionExtends.getFreeStatus();
            if(freeStatus){
                connectionExtends.setFreeStatus(false);
                final Connection connection = connectionExtends.getConnection();
                Object object = Proxy.newProxyInstance(MyDataSource.class.getClassLoader(), new Class[]{Connection.class}, new InvocationHandler() {
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        if (method.getName().equals("close")) {//当为调用close函数并且连接池正在运行，则将连接使用状态修改
                            connectionExtends.setFreeStatus(true);//
                            return null;
                        } else {
                            return method.invoke(connection, args);
                        }

                    }
                });
                return (Connection)object;
            }
        }
        return null;
    }


    public void setMinSizes(int minSizes) {
        this.minSizes = minSizes;
    }

    public void setMaxSizes(int maxSizes) {
        this.maxSizes = maxSizes;
    }

    public void setDriverClass(String driverClass) {
        this.driverClass = driverClass;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}
